package com.sping.gobang.game;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sping.gobang.pojo.datapbject.User;
import com.sping.gobang.pojo.response.MatchResponse;
import io.jsonwebtoken.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.LinkedList;
import java.util.Queue;
@Slf4j
@Component
public class Matcher {
//    创建三个匹配队列
    private Queue<User> normalQueue=new LinkedList<>();
    private Queue<User> highQueue=new LinkedList<>();
    private Queue<User> veryHighQueue=new LinkedList<>();
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RoomManager roomManager;
//    操作匹配队列的方法
//    把玩家放到匹配队列中
    public void add(User user){
        if(user.getScore()<2000){
            synchronized (normalQueue){
                normalQueue.offer(user);
                normalQueue.notify();
            }
            log.info("把玩家 "+user.getUsername()+"加入到了normalQueue中!");

        }else if(user.getScore()>=2000&&user.getScore()<3000){
            synchronized (highQueue){
                highQueue.offer(user);
                highQueue.notify();
            }
            log.info("把玩家 "+user.getUsername()+"加入到了highQueue中!");

        }else{
            synchronized (veryHighQueue){
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            log.info("把玩家 "+user.getUsername()+"加入到了veryHighQueue中!");
        }
    }
//    当玩家停止匹配的时候，就需要把玩家从匹配队列中删除
    public void remove(User user){
        if(user.getScore()<2000){
            synchronized (normalQueue){
                normalQueue.remove(user);
            }
            log.info("把玩家 "+user.getUsername()+"移除了normalQueue!");
        }else if(user.getScore()>=2000&&user.getScore()<3000){
            synchronized (highQueue){
                highQueue.remove(user);
            }
            log.info("把玩家 "+user.getUsername()+"移除了highQueue!");
        }else{
            synchronized (veryHighQueue){
                veryHighQueue.remove(user);
            }
            log.info("把玩家 "+user.getUsername()+"移除了veryHighQueue!");
        }
    }

    public Matcher(){
//        创建三个线程，分别针对这三个匹配队列，进行操作
        Thread t1=new Thread(){
            @Override
            public void run() {
               while(true){
                   handlerMatch(normalQueue);
               }
            }
        };
        t1.start();
        Thread t2=new Thread(){
            @Override
            public void run() {
                while(true){
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();
        Thread t3=new Thread(){
            @Override
            public void run() {
                while(true){
                    handlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }

    private void handlerMatch(Queue<User> matchQueue) {
      synchronized (matchQueue){
          try{
              //使用while循环判断
              while(matchQueue.size()<2){
                  //说明在同一个队列里面，不足两个人
                  matchQueue.wait();
              }
              User player1 = matchQueue.poll();
              User player2 = matchQueue.poll();
              log.info("匹配到两个玩家："+player1.getUsername()+","+player2.getUsername());
              //获取玩家的websocket的会话
              WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
              WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());
              if(session1==null){
                  //如果玩家1不在线了，就把玩家二重新放回匹配队列中
                  matchQueue.offer(player2);
                  return;
              }
              if(session2==null){
                  matchQueue.offer(player1);
                  return;
              }
              //一个玩家入队列两次
              if(session1==session2){
                  //就把玩家 1或者玩家2重新放入队列里面即可
                  matchQueue.offer(player1);
                  return;

              }
              //TODO 把这两个玩家放到一个游戏房间里面
              Room room=new Room();
              roomManager.add(room, player1.getUserId(),player2.getUserId());





              //给玩家反馈信息：你匹配到对手了
              //通过websocket返回一个message为matchSuccess这样的响应
              //要给两个玩家都返回

              MatchResponse matchResponse1=new MatchResponse();
              matchResponse1.setOk(true);
              matchResponse1.setMessage("matchSuccess");
              String json1 = objectMapper.writeValueAsString(matchResponse1);
              //服务器返回给客户端
              session1.sendMessage(new TextMessage(json1));
              MatchResponse matchResponse2=new MatchResponse();
              matchResponse2.setOk(true);
              matchResponse2.setMessage("matchSuccess");
              String json2 = objectMapper.writeValueAsString(matchResponse2);
              session2.sendMessage(new TextMessage(json2));

          }catch (IOException | java.io.IOException  | InterruptedException e){
              e.printStackTrace();
          }
      }

    }

}
